#include "ConexionServer.h"
#include "../../SDLtoolkit/Asteroide.h"
#include "../DTOCliente.h"
#include "../DTOFinHandshake.h"
#include "../DTOImage.h"
#include "../../Server/ColaClientes.h"
#include "../utils/InstanceDuplicater.h"

ConexionServer::ConexionServer(SocketProtocoloPlano* socket,SpaceBattleInterface* game,int listenPort,int broadcastPort,ColaMensajes* colaMensajesServer,const bool* conexionActiva, void* clientes) {
	this->colaMensajesServer = colaMensajesServer;
	this->enviarACliente = new ColaMensajes(SERVER_OWN);
	this->valido = true;

	this->handshake(socket,game,listenPort,broadcastPort,colaMensajesServer,enviarACliente,conexionActiva,clientes);
}

void ConexionServer::handshake(SocketProtocoloPlano* socket,SpaceBattleInterface* game,int listenPort,int broadcastPort,ColaMensajes* enviar,ColaMensajes* recibir,const bool* conexionActiva, void* clientes){
	ColaMensajes* mensajesHandshake = new ColaMensajes(SERVER_OWN);
	ConexionBidireccional* conexion = new ConexionBidireccional(socket->getOwnerIp(),socket,mensajesHandshake);

	ColaClientes* colaClientes = (ColaClientes*)clientes;

	std::list<Asteroide*> elements = game->getAsteroides();

	//Envio los asteroides del escenario
	std::list<Asteroide*>::iterator it;
	for (it = elements.begin(); it != elements.end(); ++it) {
		DTOAsteroide* dtoAsteroide = ((Asteroide*)*it)->getDTO();
		conexion->enviar(dtoAsteroide);
	}

 	//Cruzo los puertos, la conexion es cruzada
	//Pass the information of the dimension of the play scenario in the server.
	conexion->enviar(new DTOFinHandshake(broadcastPort,listenPort,game->getWidth(),game->getHeight()));

	DTOCliente* cliente= (DTOCliente*)conexion->recibir();

	if(colaClientes->isClient(cliente->getOwner()) || colaClientes->getSize() >= MAX_SERVER_LISTEN){
		cliente->setStatus(DISCONECTED);
		this->valido = false;
	}

	if(colaClientes->getSize() == 0){
		cliente->setAdmin();
	}

	this->cliente = cliente->getOwner();

	//Devuelvo el cliente como ultima instancia del handshake
	DTO* copiaClient = InstanceDuplicater::duplicate(cliente);
	conexion->enviar(cliente);

	//Cambio los puertos de mis recever y sender para iniciar la comunicacion

	this->conexionACliente = new ConexionBidireccional(socket,listenPort,broadcastPort,colaMensajesServer,enviarACliente);

	if(this->valido){
		//Lo agrego a la cola de mensajes del server, Un nuevo cliente se conecto
		colaMensajesServer->setMensaje(copiaClient);
	}

	delete conexion;
	delete mensajesHandshake;
}

void ConexionServer::addToSend(DTO* dto){
	this->enviarACliente->setMensaje(dto);
}

std::string ConexionServer::getCliente(){
	return cliente;
}

bool ConexionServer::esValida(){
	return this->conexionACliente->estaConectado() && this->valido;
}

void ConexionServer::terminar(){
	this->conexionACliente->terminar();
	this->conexionACliente->join();
}

ConexionServer::~ConexionServer(){
	delete conexionACliente;
	delete enviarACliente;
}

